package org.linuxsogood.boot.lock;

import java.util.concurrent.*;

/**
 * @author honway.liu
 * @date 2019-07-31 18:30
 * @email gm100861@gmail.com
 * @blog http://linuxsogood.org
 *
 * CountDownLatch 原子计数器类,主要用于计数.
 * 构造给一个初始值,比如20, 每次调用countDown方法时会减1,直到减到0
 * await方法后面的代码,才会继续执行.
 *
 * Semaphore 信号量,一般用于控制并发数,做限流
 * 比如我有20个线程在同时执行,但是我希望同一时间执行的线程只有3个,那么就可以定义一个大小为3的信号量
 * 每次release可以释放一个许可,acquire的时候消耗一个许可,当许可被消耗完的时候,再次获取许可会阻塞.
 * acquire也可以一次性获取多个许可,释放也可以释放多个许可
 */
public class SemaphoreExample2 {
    private static int threadCount = 20;

    public static void main(String[] args) throws InterruptedException {
        ExecutorService executorService = Executors.newCachedThreadPool();

        CountDownLatch countDownLatch = new CountDownLatch(threadCount);
        Semaphore semaphore = new Semaphore(1);

        for (int i = 0; i < threadCount; i++) {
            executorService.execute(() -> {
                try {
                    semaphore.acquire();
                    method();
                    semaphore.release();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    countDownLatch.countDown();
                }
            });
        }

        countDownLatch.await();
        System.out.println("finished...");
        executorService.shutdown();
    }

    private static void method() throws InterruptedException {
        System.out.println("current thread name: " + Thread.currentThread().getName());
        TimeUnit.MILLISECONDS.sleep(1000);
    }
}
